#include "stanza/querystanza.h"
#include "base/basedefines.h"

namespace remote {

QueryStanza::QueryStanza()
  :state_(0) {
}

QueryStanza::~QueryStanza() {
}

QueryStanza::Ptr QueryStanza::CreateQueryStanza(
  const std::string type,
  uint32 state,
  const std::string id,
  const std::string to,
  const std::string from) {

  QueryStanza::Ptr stanza(new QueryStanza);
  stanza->set_type(type);
  stanza->set_state(state);
  stanza->set_to(to);
  stanza->set_from(from);
  stanza->set_id(id);
  return stanza;
}

vzconn::ByteBuffer::Ptr QueryStanza::ToByteBuffer() {
  if(!IsValid()) {
    LOG(ERROR) << "The query stanza is not an valid stanza";
    return vzconn::ByteBuffer::Ptr();
  }
  vzconn::ByteBuffer::Ptr byte_buffer(new vzconn::ByteBuffer());
  byte_buffer->WriteString(ToString());
  return byte_buffer;
}

std::string QueryStanza::ToString() {
  Json::Value value;
  Json::StyledWriter fw;
  value[JSON_BODY]  = body_;
  value[JSON_FROM]  = from_;
  value[JSON_TO]    = to_;
  value[JSON_ID]    = id_;
  value[JSON_STATE] = state_;
  value[JSON_TYPE]  = type_;
  std::string debug_message = fw.write(value);
  LOG(INFO) << "SEND >>>>>>>>>>>>>>>>> ";
  LOG(INFO) << debug_message;
  return debug_message;
}

bool QueryStanza::Parse(const char *data, std::size_t size) {
  LOG(INFO) << "RECV <<<<<<<<<<<<<<<<< ";
  LOG(INFO).write(data, size);
  Json::Value value;
  Json::Reader reader;
  if(!reader.parse(data, data + size, value)) {
    LOG(ERROR) << reader.getFormattedErrorMessages();
    return false;
  }
  if(value[JSON_TYPE].isNull()
      || value[JSON_STATE].isNull()
      || value[JSON_ID].isNull()
      || value[JSON_TO].isNull()
      || value[JSON_FROM].isNull()) {
    LOG(ERROR) << "The protocol header invalid";
    return false;
  }

  type_   = value[JSON_TYPE].asString();
  state_  = value[JSON_STATE].asUInt();
  id_     = value[JSON_ID].asString();
  to_     = value[JSON_TO].asString();
  from_   = value[JSON_FROM].asString();
  body_   = value[JSON_BODY];

  return true;
}

bool QueryStanza::IsValid() {
  if(type_.empty() || id_.empty() || to_.empty() || from_.empty()) {
    return false;
  }
  return true;
}

}